package net.wanglu.www.zzz.rule.sva;

import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.trees.TreeGraphNode;

public class TwoPartsAsSubj extends _SvaRule {
	
	public static final Pattern Clothing = Pattern.compile("\\bbells\\b|\\bblinders\\b|\\bbloomers\\b|\\bboots\\b|\\bbraces\\b|\\bbreeches\\b|\\bbritches\\b|\\bbriefs\\b|\\bcords\\b|\\bdrawers\\b|\\bdungarees\\b|\\bflannels\\b|\\bflares\\b|\\bgloves\\b|\\bjeans\\b|\\bknickers\\b|\\bleggings\\b|\\bmittens\\b|\\boveralls\\b|\\bpajamas\\b|\\bpants\\b|\\bplus-fours\\b|\\brubbers\\b|\\bscanties\\b|\\bshoes\\b|\\bshorts\\b|\\bslacks\\b|\\bsocks\\b|\\bslippers\\b|\\bspats\\b|\\bstepins\\b|\\bstocking\\b|\\bsuspenders\\b|\\bswimming-trunks\\b|\\btights\\b|\\btrews\\b|\\btrunks\\b|\\btrousers\\b|\\bunderpants\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern Tool = Pattern.compile("\\bbellows\\b|\\bbifoclas\\b|\\bbinoculars\\b|\\bcalipers\\b|\\bchopsticks\\b|\\bclippers\\b|\\bcompasses\\b|\\bcontactlenses\\b|\\bdividers\\b|\\bedging-shears\\b|\\bforceps\\b|\\bglasses\\b|\\bgoggles\\b|\\bnail-shears\\b|\\bpincers\\b|\\bpliers\\b|\\bscales\\b|\\bscissors\\b|\\bsecateurs\\b|\\bshears\\b|\\bshades\\b|\\bsnuffers\\b|\\bspectacles\\b|\\btongs\\b|\\btweezers\\b");
	public static final Pattern PairSuit = Pattern.compile("\\bpair[s]\\b|\\bsuit[s]\\b");
	
	public int ClothingFlag = 1;
	public int ToolFlag = 2;
	public int PairSuitFlag = 3;

	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		TreeGraphNode verb = (TreeGraphNode) nst.getVerb();
		TreeGraphNode cop = (TreeGraphNode) nst.getCop();
		TreeGraphNode closestAux = (TreeGraphNode) nst.getAux();
		
		TreeGraphNode pred = verb;
		if ( cop != null) pred = cop;
		if ( closestAux != null) pred = closestAux;
		String predWord = pred.label().word();
		String predTag = pred.label().tag();
		
		if ( Clothing.matcher(subj.label().word()).find()) {
			if (Rule.PluralVerb.matcher(predTag).find() && !"was".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.ClothingFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}
		} else if ( Tool.matcher(subj.label().word()).find()) {
			if (Rule.PluralVerb.matcher(predTag).find() && !"was".equals(predWord)) {
				return null;
			} else {
				BadEgg egg = new BadEgg();
				egg.setFlag(this.ToolFlag);
				egg.setProperty(BadEgg.Error);
				egg.setViolatedRule(this);
				egg.whereIsWrong = nst;
				return egg;
			}
		} else if ( PairSuit.matcher(subj.label().word()).find()) {
			if ( "NN".equals(subj.label().tag())) {
				if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.setFlag(this.PairSuitFlag);
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					egg.whereIsWrong = nst;
					return egg;
				}							
			} else if ( "NNS".equals(subj.label().tag())) {
				if (Rule.PluralVerb.matcher(predTag).find() && !"was".equals(predWord)) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.setFlag(this.PairSuitFlag);
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					egg.whereIsWrong = nst;
					return egg;
				}				
			}
		}
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		BadEgg egg = (BadEgg) objects[0];
		sb.clear();
		if ( egg.getFlag() == this.ClothingFlag) {
			sb.append("<p>");
			sb.append("有些表示服装店名词由相等的或对称的两个部分合在一起构成的，它们作主语时，谓语动词用复数。这类名词主要有：");
			sb.append("<br>");
			sb.append("bells，blinders，bloomers，boots，braces，breeches，britches，briefs，cords，drawers，dungarees，flannels，flares，gloves，jeans，knickers，leggings，mittens，overalls，pajamas，pants，plus-fours，rubbers，scanties，shoes，shorts，slacks，socks，slippers，spats，stepins，stocking，suspenders，swimming-trunks，tights，trews，trunks，trousers，underpants");
			sb.append("</p>");
		} else if ( egg.getFlag() == this.ToolFlag) {
			sb.append("<p>");
			sb.append("有些工具和仪器名词是由相同的两个部分组成的，它们的谓语动词要用复数形式。这类名词有：");
			sb.append("<br>");
			sb.append("bellows，bifoclas，binoculars，calipers，chopsticks，clippers，compasses，contactlenses，dividers，edging-shears，forceps，glasses，goggles，nail-shears，pincers，pliers，scales，scissors，secateurs，shears，shades，snuffers，spectacles，tongs，tweezers");
			sb.append("</p>");			
		} else if ( egg.getFlag() == this.PairSuitFlag) {
			sb.append("<p>");
			sb.append("表示服装、工具、仪器之类的二合一复数名词与a/one/this/each pair of，a suit of等连用时，谓语动词的形式取决于pair，suit等词典数。例如：");
			sb.append("<br>");
			sb.append("This pair of trousers is too tight for me.");
			sb.append("<br>");
			sb.append("A suit of clothes was hung on the wall.");
			sb.append("<br>");
			sb.append("Some suits of clothes were hung on the wall.");
			sb.append("</p>");			
		}
		return sb.toString();
	}
}
